package com.cheer.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cheer.common.Page;
import com.cheer.dao.MallProductBookStoreDao;
import com.cheer.dao.MallProductDao;
import com.cheer.dto.MallAttrDTO;
import com.cheer.dto.MallProductAddDTO;
import com.cheer.dto.MallProductQueryDTO;
import com.cheer.dto.MallProductUpdateDTO;
import com.cheer.entity.*;
import com.cheer.enums.MallProductImageEnum;
import com.cheer.enums.MallProductStatusEnum;
import com.cheer.enums.MallProductTypeEnum;
import com.cheer.enums.MallProductVirTypeEnum;
import com.cheer.exception.ServiceException;
import com.cheer.service.*;
import com.cheer.vo.*;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service("mallProductService")
public class MallProductServiceImpl extends ServiceImpl<MallProductDao, MallProductEntity> implements MallProductService {

    @Value("${image.url}")
    private String imageUrl;

    @Autowired
    private MallProductDao mallProductDao;

    @Autowired
    private MallCategoryProductRelationService mallCategoryProductRelationService;

    @Autowired
    private MallCategoryService mallCategoryService;

    @Autowired
    private MallProductImageService mallProductImageService;

    @Autowired
    private MallProductAttrService mallProductAttrService;

    @Autowired
    private MallProductDescService mallProductDescService;

    @Autowired
    private MallShopService mallShopService;

    @Autowired
    private MallProductBookStoreDao mallProductBookStoreDao;


    @Override
    public Page<MallProductListVO> listByQueryCondition(MallProductQueryDTO productQueryDTO) {
        // 分页查询商品信息
        IPage<MallProductEntity> page = mallProductDao.selectPageByQueryCondition(productQueryDTO);

        // 查询每个商品包含的分类
        List<Long> productIdList = page.getRecords().stream()
                .map(MallProductEntity::getId)
                .collect(Collectors.toList());
        Map<Long, List<Long>> productCategoryMap = mallCategoryProductRelationService.listByProductIds(productIdList).stream()
                .collect(Collectors.groupingBy(MallCategoryProductRelationEntity::getProductId,
                        Collectors.mapping(MallCategoryProductRelationEntity::getCategoryId, Collectors.toList())));

        // 查询分类信息
        Set<Long> categoryIdSet = new HashSet<>();
        productCategoryMap.values().forEach(categoryIdSet::addAll);
        Map<Long, MallCategoryEntity> categoryMap;
        if (categoryIdSet.isEmpty()) {
            categoryMap = new HashMap<>();
        } else {
            categoryMap = mallCategoryService.listByIds(new ArrayList<>(categoryIdSet)).stream()
                    .collect(Collectors.toMap(MallCategoryEntity::getId, Function.identity()));
        }

        // 转换商品vo
        List<MallProductListVO> productList = page.getRecords().stream()
                .map(productEntity -> {

                    // 基础信息
                    MallProductListVO productListVO = new MallProductListVO()
                            .setId(productEntity.getId())
                            .setNumber(generateNumber(productEntity.getId()))
                            .setType(productEntity.getType())
                            .setName(productEntity.getMainTitle())
                            .setCreateTime(DateUtil.formatDateTime(productEntity.getCreateTime()))
                            .setPublishStatus(productEntity.getPublishStatus())
                            .setIsBookStock(productEntity.getIsBookStock())
                            .setStock(productEntity.getStock());

                    // 价格积分
                    if (productEntity.getMarketPrice() != null) {
                        productListVO.setMarketPrice(productEntity.getMarketPrice().stripTrailingZeros().toPlainString() + "元");
                    }
                    String displayPrice = null;
                    if (productEntity.getDisplayPrice() != null) {
                        displayPrice = productEntity.getDisplayPrice().stripTrailingZeros().toPlainString() + "元";
                    }
                    if (displayPrice != null) {
                        displayPrice += "+";
                    }
                    if (productEntity.getCredit() != null) {
                        displayPrice += productEntity.getCredit() + "分";
                    }
                    if (displayPrice != null) {
                        productListVO.setDisplayPrice(displayPrice);
                    }

                    // 分类信息
                    List<Long> categoryIdList = productCategoryMap.get(productEntity.getId());
                    if (CollectionUtils.isNotEmpty(categoryIdList)) {
                        List<String> categoryNameList = new ArrayList<>();
                        for (Long categoryId : categoryIdList) {
                            MallCategoryEntity category = categoryMap.get(categoryId);
                            if (category != null) {
                                categoryNameList.add(category.getName());
                            }
                        }

                        if (!categoryNameList.isEmpty()) {
                            productListVO.setCategory(StringUtils.join(categoryNameList, "，"));
                        }
                    }

                    return productListVO;
                })
                .collect(Collectors.toList());

        return new Page<>(page, productList);
    }

    @Override
    @Transactional
    public void add(MallProductAddDTO productAddDTO) {
        // 保存商品表
        MallProductEntity productEntity = new MallProductEntity()
                .setType(productAddDTO.getType())
                .setMainTitle(productAddDTO.getMainTitle())
                .setShortTitle(productAddDTO.getShortTitle())
                .setShopId(productAddDTO.getShopId())
                .setStock(productAddDTO.getStock())
                .setAllowRefund(productAddDTO.getAllowRefund())
                .setExchangeType(productAddDTO.getExchangeType())
                .setLimited(productAddDTO.getLimited())
                .setPublishStatus(productAddDTO.getSubmitType() == 1 ?
                        MallProductStatusEnum.PEND_REVIEW.getCode() : MallProductStatusEnum.NOT_ACTIVATED.getCode());

        MallAttrDTO mallAttrDTO = productAddDTO.getAttr().get(0);
        if (mallAttrDTO.getMarketPrice() != null) {
            productEntity.setMarketPrice(new BigDecimal(mallAttrDTO.getMarketPrice()));
        }
        if (mallAttrDTO.getDisplayPrice() != null) {
            productEntity.setDisplayPrice(new BigDecimal(mallAttrDTO.getDisplayPrice()));
        }
        if (mallAttrDTO.getCredit() != null) {
            if (!NumberUtils.isDigits(mallAttrDTO.getCredit()) || Integer.valueOf(mallAttrDTO.getCredit()) < 0) {
                throw new ServiceException("积分只能输入非负整数");
            }
            productEntity.setCredit(Integer.valueOf(mallAttrDTO.getCredit()));
        }

        if (Objects.equals(MallProductTypeEnum.VIR_OBJECT.getCode(), productAddDTO.getType())) {
            if (productAddDTO.getVirType() == null) {
                throw new ServiceException("电子券码商品类型不能为空");
            }
            productEntity.setVirType(productAddDTO.getVirType());
            productEntity.setMethod(productAddDTO.getMethod());
            productEntity.setVirImage(productAddDTO.getVirImage());
        }

        if (StringUtils.isNotBlank(productAddDTO.getKeywords())) {
            productEntity.setKeywords(StringUtils.replace(productAddDTO.getKeywords(), "，", ","));
        }

        productEntity.setPostage(productAddDTO.getPostage());
        if (!productAddDTO.getPostage()) {
            if (StringUtils.isBlank(productAddDTO.getPostagePrice())) {
                throw new ServiceException("运费不能为空");
            }
            productEntity.setPostagePrice(new BigDecimal(productAddDTO.getPostagePrice()));
        }

        mallProductDao.insert(productEntity);

        // 保存商品图片表
        saveProductImage(productEntity.getId(), productAddDTO.getThumbnailUrl(),
                productAddDTO.getDisplayImageUrl(), productAddDTO.getDescImageUrl());


        // 保存分类
        saveCategoryProduct(productEntity.getId(), productAddDTO.getCategoryIdList());

        // 保存规格
        saveProductAttr(productEntity.getId(), productAddDTO.getAttr());

        // 保存简介
        if (StringUtils.isNotBlank(productAddDTO.getDesc())) {
            MallProductDescEntity desc = new MallProductDescEntity();
            desc.setProductId(productEntity.getId());
            desc.setDescription(productAddDTO.getDesc());
            mallProductDescService.save(desc);
        }
    }

    @Override
    public MallProductInfoVO info(Long id) {
        MallProductEntity product = mallProductDao.selectById(id);
        if (product == null) {
            throw new ServiceException("商品不存在");
        }

        // 商品基本信息
        MallProductInfoVO info = new MallProductInfoVO()
                .setId(product.getId())
                .setType(product.getType())
                .setMainTitle(product.getMainTitle())
                .setShortTitle(product.getShortTitle())
                .setShopId(product.getShopId())
                .setStock(product.getStock())
                .setExchangeType(product.getExchangeType())
                .setAllowRefund(product.getAllowRefund())
                .setLimited(product.getLimited())
                .setPostage(product.getPostage())
                .setExchangeType(product.getExchangeType())
                .setKeywords(product.getKeywords());

        if (!product.getPostage()) {
            info.setPostagePrice(product.getPostagePrice().stripTrailingZeros().toPlainString());
        }

        if (Objects.equals(MallProductTypeEnum.VIR_OBJECT.getCode(), product.getType())) {
            info.setVirType(product.getVirType());
            if (Objects.equals(MallProductVirTypeEnum.USAGE_OBJECT.getCode(), product.getVirType())) {
                info.setMethod(product.getMethod());
                if (StringUtils.isNotBlank(product.getVirImage())) {
                    info.setVirImage(new ImageVO()
                            .setFullUrl(imageUrl + product.getVirImage())
                            .setShortUrl(product.getVirImage()));
                } else {
                    info.setVirImage(new ImageVO()
                            .setFullUrl("")
                            .setShortUrl(""));
                }
            }
        }

        // 商品图片
        List<MallProductImageEntity> imageList = mallProductImageService.listByProductId(id);
        List<ImageVO> displayImageUrl = new ArrayList<>();
        List<ImageVO> descImageUrl = new ArrayList<>();
        for (MallProductImageEntity image : imageList) {
            if (image.getImageType().equals(MallProductImageEnum.THUMBNAIL.getCode())) {

                info.setThumbnailUrl(new ImageVO()
                        .setFullUrl(imageUrl + image.getImageUrl())
                        .setShortUrl(image.getImageUrl()));

            } else if (image.getImageType().equals(MallProductImageEnum.DISPLAY.getCode())) {

                ImageVO imageVO = new ImageVO();
                imageVO.setFullUrl(imageUrl + image.getImageUrl());
                imageVO.setShortUrl(image.getImageUrl());
                displayImageUrl.add(imageVO);

            } else if (image.getImageType().equals(MallProductImageEnum.DESC.getCode())) {

                ImageVO imageVO = new ImageVO();
                imageVO.setFullUrl(imageUrl + image.getImageUrl());
                imageVO.setShortUrl(image.getImageUrl());
                descImageUrl.add(imageVO);
            }
        }
        info.setDisplayImageUrl(displayImageUrl);
        info.setDescImageUrl(descImageUrl);

        // 商品分类
        List<MallCategoryProductRelationEntity> relation = mallCategoryProductRelationService.listByProductId(id);
        info.setCategoryIdList(relation.stream()
                .map(MallCategoryProductRelationEntity::getCategoryId)
                .collect(Collectors.toList()));

        // 商品规格
        List<MallProductAttrEntity> attrList = mallProductAttrService.listByProductId(id);
        info.setAttr(attrList.stream()
                .map(attr -> {
                    MallAttrDTO mallAttrDTO = new MallAttrDTO();
                    mallAttrDTO.setAttr(attr.getAttrValue());
                    if (attr.getMarketPrice() != null) {
                        mallAttrDTO.setMarketPrice(attr.getMarketPrice().stripTrailingZeros().toPlainString());
                    }
                    if (attr.getDisplayPrice() != null) {
                        mallAttrDTO.setDisplayPrice(attr.getDisplayPrice().stripTrailingZeros().toPlainString());
                    }
                    if (attr.getCredit() != null) {
                        mallAttrDTO.setCredit(String.valueOf(attr.getCredit()));
                    }
                    return mallAttrDTO;
                })
                .collect(Collectors.toList()));

        // 商品简介
        MallProductDescEntity desc = mallProductDescService.getByProductId(id);
        if (desc != null) {
            info.setDesc(desc.getDescription());
        }

        return info;
    }

    @Override
    @Transactional
    public void update(MallProductUpdateDTO productUpdateDTO) {
        MallProductEntity product = mallProductDao.selectById(productUpdateDTO.getId());
        if (product == null) {
            throw new ServiceException("商品不存在");
        }
        if (product.getPublishStatus().equals(MallProductStatusEnum.REMOVED.getCode())) {
            throw new ServiceException("已下架的商品不能修改");
        }
        if (!Objects.equals(product.getShopId(), productUpdateDTO.getShopId())) {
            throw new ServiceException("商户Id不能修改");
        }

        // 更新商品表
        MallProductEntity updateProduct = new MallProductEntity();
        updateProduct.setId(productUpdateDTO.getId())
                .setType(productUpdateDTO.getType())
                .setMainTitle(productUpdateDTO.getMainTitle())
                .setShortTitle(productUpdateDTO.getShortTitle())
                .setStock(productUpdateDTO.getStock())
                .setExchangeType(productUpdateDTO.getExchangeType())
                .setAllowRefund(productUpdateDTO.getAllowRefund())
                .setLimited(productUpdateDTO.getLimited())
                .setPostage(productUpdateDTO.getPostage())
                .setPublishStatus(productUpdateDTO.getSubmitType() == 1 ?
                        MallProductStatusEnum.PEND_REVIEW.getCode() : MallProductStatusEnum.NOT_ACTIVATED.getCode());

        if (StringUtils.isNotBlank(productUpdateDTO.getKeywords())) {
            updateProduct.setKeywords(StringUtils.replace(productUpdateDTO.getKeywords(), "，", ","));
        }

        MallAttrDTO mallAttrDTO = productUpdateDTO.getAttr().get(0);
        if (mallAttrDTO.getMarketPrice() != null) {
            updateProduct.setMarketPrice(new BigDecimal(mallAttrDTO.getMarketPrice()));
        }
        if (mallAttrDTO.getDisplayPrice() != null) {
            updateProduct.setDisplayPrice(new BigDecimal(mallAttrDTO.getDisplayPrice()));
        }
        if (mallAttrDTO.getCredit() != null) {
            if (!NumberUtils.isDigits(mallAttrDTO.getCredit()) || Integer.valueOf(mallAttrDTO.getCredit()) < 0) {
                throw new ServiceException("积分只能输入非负整数");
            }
            updateProduct.setCredit(Integer.valueOf(mallAttrDTO.getCredit()));
        }

        if (!productUpdateDTO.getPostage()) {
            if (StringUtils.isBlank(productUpdateDTO.getPostagePrice())) {
                throw new ServiceException("运费不能为空");
            }
            updateProduct.setPostagePrice(new BigDecimal(productUpdateDTO.getPostagePrice()));
        }

        if (Objects.equals(MallProductTypeEnum.VIR_OBJECT.getCode(), productUpdateDTO.getType())) {
            if (productUpdateDTO.getVirType() == null) {
                throw new ServiceException("电子券码商品类型不能为空");
            }
            updateProduct.setVirType(productUpdateDTO.getVirType());
            updateProduct.setMethod(productUpdateDTO.getMethod());
            updateProduct.setVirImage(productUpdateDTO.getVirImage());
        }

        if (product.getSpecial() && updateProduct.getStock() > product.getStock()) {
            updateProduct.setReset(false);
        }

        mallProductDao.update(updateProduct);

        // 更新商品图片
        mallProductImageService.deleteByProductId(productUpdateDTO.getId());

        saveProductImage(productUpdateDTO.getId(), productUpdateDTO.getThumbnailUrl(),
                productUpdateDTO.getDisplayImageUrl(), productUpdateDTO.getDescImageUrl());

        // 更新商品分类
        mallCategoryProductRelationService.deleteByProductId(productUpdateDTO.getId());

        saveCategoryProduct(productUpdateDTO.getId(), productUpdateDTO.getCategoryIdList());

        // 更新商品规格
        mallProductAttrService.deleteByProductId(productUpdateDTO.getId());

        saveProductAttr(productUpdateDTO.getId(), productUpdateDTO.getAttr());

        // 保存简介
        if (StringUtils.isNotBlank(productUpdateDTO.getDesc())) {
            mallProductDescService.saveOrUpdateByProductId(productUpdateDTO.getId(), productUpdateDTO.getDesc());
        } else {
            mallProductDescService.deleteByProductId(productUpdateDTO.getId());
        }
    }

    @Override
    @Transactional
    public void delete(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }

        // 删除商品表
        mallProductDao.deleteBatchIds(ids);

        // 删除图片表
        mallProductImageService.deleteByProductIds(ids);

        // 删除商品分类关联表
        mallCategoryProductRelationService.deleteByProductIds(ids);

        // 删除规格表
        mallProductAttrService.deleteByProductIds(ids);

        // 删除简介表
        mallProductDescService.deleteByProductIds(ids);
    }

    @Override
    @Transactional
    public void review(Long id) {
        MallProductEntity product = mallProductDao.selectById(id);
        if (product == null) {
            throw new ServiceException("商品不存在");
        }
        if (!Objects.equals(product.getPublishStatus(), MallProductStatusEnum.PEND_REVIEW.getCode())) {
            throw new ServiceException("只有待审核的商品可以进行审核");
        }

        MallProductEntity updateProduct = new MallProductEntity()
                .setId(id)
                .setPublishStatus(MallProductStatusEnum.PASSED.getCode());
        mallProductDao.updateById(updateProduct);
        // distributeCategory(product);
        mallCategoryProductRelationService.updateStatusByProductId(id, true);
    }

    /**
     * TODO 自动填写分类功能暂时注释
     * 将审核通过的产品存入到指定分类中
     * @param product 产品ID
     */
    public void distributeCategory(MallProductEntity product){

        if(product.getLottery() == true){
            return;
        }
        // 全部
        Long categoryAllId = 23L;
        // 团团周边
        Long categoryTswWeal = 25L;
        // 其他好物
        Long categoryOther = 26L;
        // 团省委shopID
        Long tswShopId = 21L;
        // 非奖品
        Long shopId = product.getShopId();
        // 将商品添加到全部分类中
        List<MallCategoryProductRelationEntity> productCategoryList = mallCategoryProductRelationService.listByProductId(product.getId());
        if(productCategoryList == null){
            productCategoryList = new ArrayList<>();
        }
        addCategory(product, categoryAllId, productCategoryList);
        if(shopId.equals(tswShopId)){
            addCategory(product, categoryTswWeal, productCategoryList);
        }else{
            addCategory(product, categoryOther, productCategoryList);
        }
    }

    private void addCategory(MallProductEntity product, Long categoryTswWeal, List<MallCategoryProductRelationEntity> productCategoryList) {
        Optional<MallCategoryProductRelationEntity> tswCategoryOpt = productCategoryList.stream().filter((categoryRelation) -> categoryRelation.getCategoryId().equals(categoryTswWeal)).findAny();
        if (tswCategoryOpt.isPresent() == false) {
            // 添加到全部中
            Long maxSort = mallCategoryProductRelationService.getCategoryMaxId(categoryTswWeal);
            MallCategoryProductRelationEntity productRelationEntity = new MallCategoryProductRelationEntity();
            productRelationEntity.setCategoryId(categoryTswWeal)
                    .setProductId(product.getId())
                    .setShowStatus(true)
                    .setShowStatus(true);
            if(maxSort == null){
                productRelationEntity.setSort(0L);
            }else{
                productRelationEntity.setSort(maxSort + 1);
            }
            // 新增到
            mallCategoryProductRelationService.save(productRelationEntity);
        }
    }


    @Override
    @Transactional
    public void remove(Long id) {
        MallProductEntity product = mallProductDao.selectById(id);
        if (product == null) {
            throw new ServiceException("商品不存在");
        }
        if (!Objects.equals(product.getPublishStatus(), MallProductStatusEnum.PASSED.getCode())) {
            throw new ServiceException("只有已上架的商品可以进行下架操作");
        }

        MallProductEntity updateProduct = new MallProductEntity();
        updateProduct.setId(id);
        updateProduct.setPublishStatus(MallProductStatusEnum.REMOVED.getCode());
        mallProductDao.updateById(updateProduct);

        mallCategoryProductRelationService.updateStatusByProductId(id, false);
    }

    @Override
    public Integer passedAndRemovedCount() {
        return mallProductDao.selectCountByStatus(Lists.newArrayList(MallProductStatusEnum.PASSED.getCode(),
                MallProductStatusEnum.REMOVED.getCode()));
    }

    @Override
    public Integer reviewCount() {
        return mallProductDao.selectCountByStatus(Lists.newArrayList(MallProductStatusEnum.PEND_REVIEW.getCode()));
    }

    @Override
    public Integer countByShopIdAndStatus(Long shopId, Integer publishStatus) {
        return mallProductDao.selectCountByShopIdAndStatus(shopId, publishStatus);
    }

    @Override
    public List<SimpleObjectVO> listProductSimpleByIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return new ArrayList<>();
        }

        List<MallProductEntity> productList = mallProductDao.selectMainTitleByIds(ids);

        return productList.stream()
                .map(mallProductEntity -> new SimpleObjectVO()
                        .setId(mallProductEntity.getId())
                        .setName(mallProductEntity.getMainTitle()))
                .collect(Collectors.toList());
    }

    @Override
    public List<SimpleObjectVO> listPassed() {
        List<MallProductEntity> productList = mallProductDao.selectMainTitleByPublishStatus(MallProductStatusEnum.PASSED.getCode());

        return productList.stream()
                .map(mallProductEntity -> new SimpleObjectVO()
                        .setId(mallProductEntity.getId())
                        .setName(mallProductEntity.getMainTitle()))
                .collect(Collectors.toList());
    }

    @Override
    public Page<MallProductFrontListVO> listByCategoryId(Integer pageNum, Integer pageSize, Long categoryId) {
        // 分页查询分类下的商品id
        IPage<MallCategoryProductRelationEntity> page = mallCategoryProductRelationService.listByCategoryId(pageNum,
                pageSize, categoryId);
        // 根据商品Id查询商品信息
        List<Long> productIdList = page.getRecords().stream()
                .map(MallCategoryProductRelationEntity::getProductId)
                .collect(Collectors.toList());

        Map<Long, Date> productIdMapDate = new HashMap<>();
        if(CollectionUtil.isNotEmpty(productIdList)){
            List<MallProductBookStoreEntity> mallProductBookStoreEntities = mallProductBookStoreDao
                    .selectList(new QueryWrapper<MallProductBookStoreEntity>().lambda().in(MallProductBookStoreEntity::getProductId, productIdList));
            productIdMapDate = mallProductBookStoreEntities.stream().collect(Collectors.toMap(MallProductBookStoreEntity::getProductId, MallProductBookStoreEntity::getBookDate));
        }

        List<MallProductEntity> productList = CollectionUtils.isEmpty(productIdList) ? new ArrayList<>() :
                mallProductDao.selectBatchIds(productIdList);
        productList = productList.stream().filter(product -> !product.getLottery()).collect(Collectors.toList());
        Map<Long, MallProductEntity> productMap = productList.stream()
                .collect(Collectors.toMap(MallProductEntity::getId, Function.identity()));

        // 根据商品Id查询图片信息
        List<MallProductImageEntity> productImageList = mallProductImageService.listByProductIdsAndType(productIdList,
                MallProductImageEnum.THUMBNAIL.getCode());
        Map<Long, MallProductImageEntity> productImageMap = productImageList.stream()
                .collect(Collectors.toMap(MallProductImageEntity::getProductId, Function.identity()));

        // 封装商品VO
        Map<Long, Date> finalProductIdMapDate = productIdMapDate;
        List<MallProductFrontListVO> productListVOS = productIdList.stream()
                .filter(productId -> productImageMap.get(productId) != null && productMap.get(productId) != null)
                .map(productId -> {
                    MallProductEntity product = productMap.get(productId);
                    MallProductFrontListVO productListVO = new MallProductFrontListVO()
                            .setId(product.getId())
                            .setExchangeType(product.getExchangeType())
                            .setName(product.getShortTitle())
                            .setStock(product.getStock())
                            .setLimited(product.getLimited())
                            .setIsBookStock(product.getIsBookStock())
                            .setReset(false)
                            .setCountDownSecond(0L);

                    if (product.getSpecial()) {
                        productListVO.setReset(product.getReset());
                    }

                    MallProductImageEntity productImage = productImageMap.get(product.getId());
                    if (productImage != null) {
                        productListVO.setThumbnailUrl(imageUrl + productImage.getImageUrl());
                    }

                    if (StringUtils.isNotBlank(product.getKeywords())) {
                        productListVO.setKeywords(Arrays.asList(StringUtils.split(product.getKeywords(), ",")));
                    }

                    if (product.getMarketPrice() != null) {
                        productListVO.setMarketPrice(product.getMarketPrice().stripTrailingZeros().toPlainString());
                    }

                    if (product.getDisplayPrice() != null) {
                        productListVO.setDisplayPrice(product.getDisplayPrice().stripTrailingZeros().toPlainString());
                    }

                    if (product.getCredit() != null) {
                        productListVO.setCredit(product.getCredit());
                    }
                    if(ObjectUtil.isNotNull(finalProductIdMapDate.get(productId))){
                        // 获取剩余秒数
                        Date date = finalProductIdMapDate.get(productId);
                        long between = DateUtil.between(new Date(), date, DateUnit.SECOND);
                        productListVO.setCountDownSecond(between);
                    }
                    return productListVO;
                })
                .collect(Collectors.toList());

        return new Page<>(page, productListVOS);
    }

    @Override
    public Page<MallProductFrontListVO> search(Integer pageNum, Integer pageSize, String keyword) {
        IPage<MallProductEntity> page = mallProductDao.selectPageByKeyword(pageNum, pageSize, keyword);

        // 查询商品图片
        List<Long> productIdList = page.getRecords().stream()
                .map(MallProductEntity::getId)
                .collect(Collectors.toList());
        List<MallProductImageEntity> productImageList = mallProductImageService.listByProductIdsAndType(productIdList,
                MallProductImageEnum.THUMBNAIL.getCode());
        Map<Long, MallProductImageEntity> productImageMap = productImageList.stream().collect(
                Collectors.toMap(MallProductImageEntity::getProductId, Function.identity()));

        List<MallProductFrontListVO> productListVOS = page.getRecords().stream()
                .map(product -> {
                    MallProductFrontListVO productListVO = new MallProductFrontListVO()
                            .setId(product.getId())
                            .setExchangeType(product.getExchangeType())
                            .setName(product.getShortTitle())
                            .setStock(product.getStock())
                            .setLimited(product.getLimited())
                            .setReset(false);

                    if (product.getSpecial()) {
                        productListVO.setReset(product.getReset());
                    }

                    MallProductImageEntity productImage = productImageMap.get(product.getId());
                    if (productImage != null) {
                        productListVO.setThumbnailUrl(imageUrl + productImage.getImageUrl());
                    }

                    if (StringUtils.isNotBlank(product.getKeywords())) {
                        productListVO.setKeywords(Arrays.asList(StringUtils.split(product.getKeywords(), ",")));
                    }

                    if (product.getMarketPrice() != null) {
                        productListVO.setMarketPrice(product.getMarketPrice().stripTrailingZeros().toPlainString());
                    }

                    if (product.getDisplayPrice() != null) {
                        productListVO.setDisplayPrice(product.getDisplayPrice().stripTrailingZeros().toPlainString());
                    }

                    if (product.getCredit() != null) {
                        productListVO.setCredit(product.getCredit());
                    }

                    return productListVO;
                })
                .collect(Collectors.toList());

        return new Page<>(page, productListVOS);
    }

    @Override
    public MallProductFrontInfoVO frontInfo(Long id) {
        MallProductEntity product = mallProductDao.selectById(id);
        if (product == null) {
            throw new ServiceException("商品不存在");
        }

        // 商品基本信息
        MallProductFrontInfoVO productInfoVO = new MallProductFrontInfoVO()
                .setId(product.getId())
                .setType(product.getType())
                .setExchangeType(product.getExchangeType())
                .setVirType(product.getVirType())
                .setName(product.getMainTitle())
                .setNumber(generateNumber(product.getId()))
                .setStock(product.getStock())
                .setLimited(product.getLimited())
                .setPostage(product.getPostage());

        if (StringUtils.isNotBlank(product.getKeywords())) {
            productInfoVO.setKeywords(Arrays.asList(StringUtils.split(product.getKeywords(), ",")));
        }

        if (product.getMarketPrice() != null) {
            productInfoVO.setMarketPrice(product.getMarketPrice().stripTrailingZeros().toPlainString());
        }

        if (product.getDisplayPrice() != null) {
            productInfoVO.setDisplayPrice(product.getDisplayPrice().stripTrailingZeros().toPlainString());
        }

        if (product.getCredit() != null) {
            productInfoVO.setCredit(product.getCredit());
        }

        if (!product.getPostage() && product.getPostagePrice() != null) {
            productInfoVO.setPostagePrice(product.getPostagePrice().stripTrailingZeros().toPlainString());
        }

        // 商品图片
        List<MallProductImageEntity> productImageList = mallProductImageService.listByProductId(id);
        List<String> displayImageUrl = new ArrayList<>();
        List<String> descImageUrl = new ArrayList<>();
        for (MallProductImageEntity productImage : productImageList) {
            if (Objects.equals(productImage.getImageType(), MallProductImageEnum.THUMBNAIL.getCode())) {
                productInfoVO.setThumbnailUrl(imageUrl + productImage.getImageUrl());
            } else if (Objects.equals(productImage.getImageType(), MallProductImageEnum.DISPLAY.getCode())) {
                displayImageUrl.add(imageUrl + productImage.getImageUrl());
            } else if (Objects.equals(productImage.getImageType(), MallProductImageEnum.DESC.getCode())) {
                descImageUrl.add(imageUrl + productImage.getImageUrl());
            }
        }
        productInfoVO.setDisplayImageUrl(displayImageUrl);
        productInfoVO.setDescImageUrl(descImageUrl);

        // 商品简介
        MallProductDescEntity productDescEntity = mallProductDescService.getByProductId(id);
        if (productDescEntity != null) {
            productInfoVO.setDesc(productDescEntity.getDescription());
        }

        MallShopEntity shop = mallShopService.getById(product.getShopId());
        if (shop != null) {
            productInfoVO.setPhone(shop.getContactPhone());
        }

        // 规格属性
        List<MallProductAttrEntity> productAttrList = mallProductAttrService.listByProductId(id);
        productInfoVO.setAttrs(productAttrList.stream()
                .map(attr -> {
                    MallAttrDTO mallAttrDTO = new MallAttrDTO();
                    mallAttrDTO.setAttr(attr.getAttrValue());
                    if (attr.getMarketPrice() != null) {
                        mallAttrDTO.setMarketPrice(attr.getMarketPrice().stripTrailingZeros().toPlainString());
                    }
                    if (attr.getDisplayPrice() != null) {
                        mallAttrDTO.setDisplayPrice(attr.getDisplayPrice().stripTrailingZeros().toPlainString());
                    }
                    if (attr.getCredit() != null) {
                        mallAttrDTO.setCredit(String.valueOf(attr.getCredit()));
                    }
                    return mallAttrDTO;
                })
                .collect(Collectors.toList()));

        return productInfoVO;
    }

    @Override
    public Boolean minusStock(Long id, Integer quantity) {
        return mallProductDao.minusStock(id, quantity) > 0;
    }

    @Override
    public MallProductEntity getMethodById(Long id) {
        return mallProductDao.selectMethodById(id);
    }

    @Override
    public void deleteByShopIds(List<Long> shopIds) {
        if (CollectionUtils.isEmpty(shopIds)) {
            return;
        }

        delete(mallProductDao.selectIdByShopId(shopIds).stream()
                .map(MallProductEntity::getId)
                .collect(Collectors.toList()));
    }

    @Override
    public void addStock(Long id, Integer quantity) {
        mallProductDao.addStock(id, quantity);
    }

    @Override
    public List<MallProductEntity> listByShopId(Long dxxShopId) {

        return mallProductDao.selectIdByShopId(Lists.newArrayList(dxxShopId));
    }

    @Override
    public void updateIsBookStock(Long productId, int status) {
        MallProductEntity product = getById(productId);
        product.setIsBookStock(status);
        updateById(product);
    }


    /**
     * 生成编号
     */
    private String generateNumber(Long id) {
        String currCount = StringUtils.leftPad(String.valueOf(id), 6, '0');
        return "X" + currCount;
    }

    /**
     * 保存商品图片
     */
    private void saveProductImage(Long productId, String thumbnailUrl, List<String> displayImageUrl, List<String> descImageUrl) {
        List<MallProductImageEntity> imageList = new ArrayList<>();

        MallProductImageEntity thumbnail = new MallProductImageEntity()
                .setProductId(productId)
                .setImageType(MallProductImageEnum.THUMBNAIL.getCode())
                .setImageUrl(thumbnailUrl);
        imageList.add(thumbnail);

        for (int i = 0; i < displayImageUrl.size(); i++) {
            MallProductImageEntity displayImage = new MallProductImageEntity()
                    .setProductId(productId)
                    .setImageType(MallProductImageEnum.DISPLAY.getCode())
                    .setImageUrl(displayImageUrl.get(i))
                    .setSort((long) i);
            imageList.add(displayImage);
        }

        if (CollectionUtils.isNotEmpty(descImageUrl)) {
            for (int i = 0; i < descImageUrl.size(); i++) {
                MallProductImageEntity descImage = new MallProductImageEntity()
                        .setProductId(productId)
                        .setImageType(MallProductImageEnum.DESC.getCode())
                        .setImageUrl(descImageUrl.get(i))
                        .setSort((long) i);
                imageList.add(descImage);
            }
        }

        mallProductImageService.saveBatch(imageList);
    }

    /**
     * 保存商品分类关联
     */
    private void saveCategoryProduct(Long productId, List<Long> categoryIdList) {
        if (CollectionUtils.isNotEmpty(categoryIdList)) {
            List<MallCategoryProductRelationEntity> relationList = new ArrayList<>();
            for (Long categoryId : categoryIdList) {
                MallCategoryProductRelationEntity relation = new MallCategoryProductRelationEntity()
                        .setProductId(productId)
                        .setCategoryId(categoryId)
                        .setShowStatus(false);
                relationList.add(relation);
            }
            mallCategoryProductRelationService.saveBatch(relationList);
        }
    }

    /**
     * 保存商品规格
     */
    private void saveProductAttr(Long productId, List<MallAttrDTO> attrs) {
        if (CollectionUtils.isNotEmpty(attrs)) {
            List<MallProductAttrEntity> attrList = new ArrayList<>();
            for (MallAttrDTO attr : attrs) {
                MallProductAttrEntity productAttr = new MallProductAttrEntity()
                        .setProductId(productId)
                        .setAttrValue(attr.getAttr());

                if (attr.getMarketPrice() != null) {
                    productAttr.setMarketPrice(new BigDecimal(attr.getMarketPrice()));
                }
                if (attr.getDisplayPrice() != null) {
                    productAttr.setDisplayPrice(new BigDecimal(attr.getDisplayPrice()));
                }
                if (attr.getCredit() != null) {
                    if (!NumberUtils.isDigits(attr.getCredit()) || Integer.valueOf(attr.getCredit()) < 0) {
                        throw new ServiceException("积分只能输入非负整数");
                    }
                    productAttr.setCredit(Integer.valueOf(attr.getCredit()));
                }

                attrList.add(productAttr);
            }
            mallProductAttrService.saveBatch(attrList);
        }
    }
}